package com.hmdp.config;

import com.hmdp.utils.LoginIntercepter;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    /**
     * 需要这样做的原因：
     *
     * 拦截器实例化时机
     * 拦截器在 Spring 上下文初始化阶段就被创建，如果使用 @Component + @Autowired：
     * 拦截器的依赖注入会在 Spring 上下文初始化阶段完成前执行
     * 而 WebMvcConfigurer 相关配置可能还未完成
     * 拦截器会被 Spring 提前实例化
     * 但此时 WebMvcConfigurer 相关配置可能未完成 --- 比如  路径匹配规则：决定哪些请求会被拦截的规则配置。视图解析器：处理请求结果渲染的组件
     * 容易导致循环依赖或配置顺序问题
     * 控制反转的边界
     * 当手动 new LoginIntercepter() 时：
     *
     * 该对象不会被 Spring 管理
     * 其中的 @Autowired stringRedisTemplate 注解不会生效
     * 则必须显式传递已注入的 Bean（通过构造函数参数）---new LoginIntercepter(stringRedisTemplate)
     * 推荐模式
     * 这种模式属于"构造器注入 + 手动装配"，相比自动注入：
     * 更明确依赖关系
     * 避免隐式的 Bean 加载顺序问题
     * 符合拦截器需要早于请求处理初始化的特性
     */
    @Resource
    private StringRedisTemplate stringRedisTemplate;// 注入StringRedisTemplate

    //添加拦截器
     @Override
     public void addInterceptors(InterceptorRegistry registry) {
         /**应该创建拦截器对象  new LoginIntercepter(stringRedisTemplate)，为什么不使用自动注入？解释如上
                 */
         registry.addInterceptor(new LoginIntercepter(stringRedisTemplate))  // 装在拦截器类LoginIntercepter
                 .excludePathPatterns(
                         "/user/code",
                         "/user/login",
                         "/shop/**",
                         "/shop-type/**",
                         "/upload/**",
                         "/blog/hot",
                         "/voucher/**").order(1);  // 不拦截 哪些请求：登录和验证码请求
     }
}
